#!/usr/bin/env python3
# PYTHON_ARGCOMPLETE_OK
import argparse
import os
import logging
from os.path import join

import build_helper
import kconfiglib

build_helper.check_python_min_version()

try:
    import argcomplete
except ImportError:
    argcomplete = None


def _cmake_contents(kconfig, header):
    chunks = [header]
    add = chunks.append
    config_vars = []

    for sym in kconfig.unique_defined_syms:
        # _write_to_conf is determined when the value is calculated. This
        # is a hidden function call due to property magic.
        val = sym.str_value
        if not sym._write_to_conf:
            continue
        if sym.orig_type in (kconfiglib.BOOL, kconfiglib.TRISTATE) and val == "n":
            val = ""
        add('set({}{} "{}")\n'.format(kconfig.config_prefix, sym.name, val))
        config_vars.append(str(kconfig.config_prefix + sym.name))
    add("set(CONFIGS_LIST {})\n".format(";".join(config_vars)))
    return "".join(chunks)


def write_cmake(kconfig, filename, gui):
    cmake_conf_header = "# Generated by gencmakeconfig.py\n"
    cmake_conf_header += "### DO NOT edit this file!! ###\n\n"
    cmake_conf_content = _cmake_contents(kconfig, cmake_conf_header)
    # don't change file info if config no change
    if os.path.exists(filename):
        with open(filename) as f:
            if f.read() == cmake_conf_content:
                return
    f = open(filename, "w")
    f.write(cmake_conf_content)
    f.close()


def write_all_configs(kconfig):
    conf = {}

    for sym in kconfig.unique_defined_syms:
        conf[str(sym.name)] = "<{}>".format(kconfiglib.TYPE_TO_STR[sym.orig_type])

    with open(join(build_helper.BUILD_OUTPUT_DIR, "config_map.sh"), "w") as fp:
        fp.write(
            """#!/bin/bash
            unset _BUILD_KCONFIG_MAP
            declare -g -A _BUILD_KCONFIG_MAP
            \n"""
        )
        fp.write(
            "\n".join(
                ("_BUILD_KCONFIG_MAP['{0}=']='{1}'".format(k, v) for k, v in conf.items())
            )
        )


def load_board_config(path):
    logging.debug("load %s", path)

    kconf = kconfiglib.Kconfig(
        build_helper.KCONFIG_PATH, suppress_traceback=True, warn=True
    )
    kconf.load_config(path)

    return kconf


def main():
    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawDescriptionHelpFormatter, description=__doc__
    )

    parser.add_argument(
        "config", metavar="CONFIGURATION", help="Input configuration file"
    )

    if argcomplete:
        argcomplete.autocomplete(parser)
    args = parser.parse_args()

    kconfig = load_board_config(args.config)

    write_cmake(kconfig, "config.cmake", False)
    write_all_configs(kconfig)


if __name__ == "__main__":
    main()
